﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gype.UI;
using System.Drawing;

namespace Gype.GUI.Components
{
    public class Button : Component 
    {
        internal override void RenderObject()
        {
            if (mManager == null)
                throw new InvalidOperationException("Unable to render a control with no manager attached!");

            var targetLocation = Location;

            var target = mManager.Target;
            target.DrawRoundedRectangle(new SlimDX.Vector2(targetLocation.X, targetLocation.Y), new SlimDX.Vector2(Size.Width, Size.Height), 4, 4, BrushCollection.ButtonBorder, 1);

            

            if (mIsHighlighted)
            {
                mTextElem.Color = BrushCollection.ButtonTextBrushHighlight;

                Gype.UI.Brush baseBrush = mIsPressed ? BrushCollection.ButtonDown : BrushCollection.ButtonOverBrush;

                target.FillRoundedRectangle(new SlimDX.Vector2(targetLocation.X + 2, targetLocation.Y + 2), new SlimDX.Vector2(Size.Width - 4, Size.Height - 4), 4,4, baseBrush);
                target.FillRoundedRectangle(new SlimDX.Vector2(targetLocation.X + 2, targetLocation.Y + 2), new SlimDX.Vector2(Size.Width - 4, Size.Height - 4), 4, 4, BrushCollection.ButtonHighlight);
            }
            else
            {
                target.FillRoundedRectangle(new SlimDX.Vector2(targetLocation.X + 2, targetLocation.Y + 2), new SlimDX.Vector2(Size.Width - 4, Size.Height - 4), 4, 4, BrushCollection.ButtonUp);
                mTextElem.Color = BrushCollection.ButtonTextBrush;
            }

            float textOffset = mIsPressed ? 1 : 0;
            mTextElem.DrawText(Text, new SlimDX.Vector2(targetLocation.X + 3 - textOffset, targetLocation.Y + 0.10f * Size.Height - textOffset), new SlimDX.Vector2(Size.Width - 4, Size.Height * 0.795f));
        }

        internal override void RenderTopLevel()
        {
        }

        internal override void AttachedToManager(Manager mgr)
        {
            mManager = mgr;
            mTextElem = new TextElement(TextCollection.Arial);
            mTextElem.Color = BrushCollection.ButtonTextBrush;
        }

        internal override void OnMessage(ControlMessage message)
        {
            base.OnMessage(message);

            switch (message.Message)
            {
                case Win32Native.WM.MOUSEMOVE:
                    handleMouseMoved(message as MouseMessage);
                    break;

                case Win32Native.WM.LBUTTONDBLCLK:
                    handleDoubleClick(message as MouseMessage);
                    break;

                case Win32Native.WM.LBUTTONDOWN:
                    handleButtonDown(message as MouseMessage);
                    break;

                case Win32Native.WM.LBUTTONUP:
                    handleButtonUp(message as MouseMessage, Win32Native.ModifierKeys.MK_LBUTTON);
                    break;

            }
        }

        private void handleDoubleClick(MouseMessage msg)
        {
            if (ClientRectangle.Contains(msg.X, msg.Y) && !msg.IsHandled)
            {
                msg.IsHandled = true;
                if ((msg.Modifiers & Win32Native.ModifierKeys.MK_LBUTTON) != 0)
                {
                    mIsPressed = true;
                }
            }
        }

        private void handleButtonDown(MouseMessage msg)
        {
            if (msg.X >= 0 && msg.X <= Size.Width &&
                msg.Y >= 0 && msg.Y <= Size.Height && !msg.IsHandled)
            {
                msg.IsHandled = true;
                if ((msg.Modifiers & Win32Native.ModifierKeys.MK_LBUTTON) != 0)
                {
                    mIsPressed = true;
                }
            }
        }

        private void handleButtonUp(MouseMessage msg, Win32Native.ModifierKeys keys)
        {
            if (ClientRectangle.Contains(msg.X, msg.Y) && !msg.IsHandled)
            {
                msg.IsHandled = true;
                if ((keys & Win32Native.ModifierKeys.MK_LBUTTON) != 0)
                {
                    if (Click != null)
                        Click(this);

                    mIsPressed = false;
                }
            }
            else
            {
                if ((keys & Win32Native.ModifierKeys.MK_LBUTTON) != 0)
                    mIsPressed = false;
            }
        }

        private void handleMouseMoved(MouseMessage msg)
        {
            PointF pos = Location;
            PointF maxPos = pos;
            maxPos.X += Size.Width;
            maxPos.Y += Size.Height;

            if (msg.X >= 0 && msg.X <= Size.Width &&
                msg.Y >= 0 && msg.Y <= Size.Height && !msg.IsHandled)
            {
                msg.IsHandled = true;
                mIsHighlighted = true;
                msg.IsHandled = true;
            }
            else
            {
                mIsHighlighted = false;
            }
        }

        public delegate void ButtonClickDelegate(Button sender);

        public event ButtonClickDelegate Click;

        public string Text { get; set; }

        private bool mIsHighlighted = false;
        private bool mIsPressed = false;
        private TextElement mTextElem;
        private Manager mManager;
    }
}
